﻿using System;
using System.ServiceModel.Description;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Query;
using XrmLibrary.Connections;

namespace XrmLibrary.Adapters
{
    public class OrganizationServiceAdapter : ServiceAdapterBase<IOrganizationService>, IOrganizationServiceAdapter
    {
        private readonly OrganizationServiceProxy _proxy;
        private readonly AutoRefreshSecurityToken<OrganizationServiceProxy, IOrganizationService> _proxyManager;

        public OrganizationServiceAdapter(IServiceConfiguration<IOrganizationService> serviceConfiguration, ClientCredentials clientCredentials) : base(serviceConfiguration, clientCredentials)
        {
            _proxy = new OrganizationServiceProxy(serviceConfiguration, clientCredentials);
            _proxyManager = new AutoRefreshSecurityToken<OrganizationServiceProxy, IOrganizationService>(_proxy);

        }

        public OrganizationServiceAdapter(IServiceConfiguration<IOrganizationService> serviceConfiguration, SecurityTokenResponse securityTokenResponse) : base(serviceConfiguration, securityTokenResponse)
        {
            _proxy = new OrganizationServiceProxy(serviceConfiguration, securityTokenResponse);
            _proxyManager = new AutoRefreshSecurityToken<OrganizationServiceProxy, IOrganizationService>(_proxy);
        }

        public OrganizationServiceAdapter(Uri uri, Uri homeRealmUri, ClientCredentials clientCredentials, ClientCredentials deviceCredentials) : base(uri, homeRealmUri, clientCredentials, deviceCredentials)
        {
            _proxy = new OrganizationServiceProxy(uri, homeRealmUri, clientCredentials, deviceCredentials);
            _proxyManager = new AutoRefreshSecurityToken<OrganizationServiceProxy, IOrganizationService>(_proxy);
        }

        protected override SecurityTokenResponse AuthenticateDeviceCore()
        {
            return _proxyManager.AuthenticateDevice();
        }

        protected override void AuthenticateCore()
        {
            _proxyManager.PrepareCredentials();
            base.AuthenticateCore();
        }

        protected override void ValidateAuthentication()
        {
            _proxyManager.RenewTokenIfRequired();
            base.ValidateAuthentication();
        }

        public virtual Guid Create(Entity entity)
        {
            return _proxy.Create(entity);
        }

        public virtual Entity Retrieve(string entityName, Guid id, ColumnSet columnSet)
        {
            return _proxy.Retrieve(entityName, id, columnSet);
        }

        public void Update(Entity entity)
        {
            _proxy.Update(entity);
        }

        public void Delete(string entityName, Guid id)
        {
            _proxy.Delete(entityName, id);
        }

        public OrganizationResponse Execute(OrganizationRequest request)
        {
            return _proxy.Execute(request);
        }

        public void Associate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
        {
            _proxy.Associate(entityName, entityId, relationship, relatedEntities);
        }

        public void Disassociate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
        {
            _proxy.Disassociate(entityName, entityId, relationship, relatedEntities);
        }

        public EntityCollection RetrieveMultiple(QueryBase query)
        {
            return _proxy.RetrieveMultiple(query);
        }

    }
}
